package com.yunquan.ohana.utils

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.net.Uri
import android.net.wifi.WifiManager
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import android.telephony.TelephonyManager
import java.io.*
import java.util.*


/**
 * 系统操作工具类$
 * @author yjp
 * @date 2020/3/31 9:50
 */
@SuppressLint("ConstantLocale")
object SystemUtils {
    /**
     * 获取当前手机系统语言。
     *
     * @return 返回当前系统语言。例如：当前设置的是“中文-中国”，则返回“zh-CN”
     */
    val LANGUAGE by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { Locale.getDefault().language }

    /**
     * 获取当前系统上的语言列表(Locale列表)
     *
     * @return 语言列表
     */
    val LANGUAGE_LIST by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { Locale.getAvailableLocales() }

    /**
     * 获取当前手机系统版本号
     *
     * @return 系统版本号
     */
    val SYSTEM_VERSION by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { android.os.Build.VERSION.RELEASE }

    /**
     * 获取手机型号
     *
     * @return 手机型号
     */
    val PHONE_MODEL by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { android.os.Build.MODEL }

    /**
     * 获取手机厂商
     *
     * @return 手机厂商
     */
    val PHONE_BRAND by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { android.os.Build.BRAND }

    /**
     * 版本名
     */
    val VERSION_NAME by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { getPackageInfo()?.versionName }

    /**
     * 版本号
     */
    val VERSION_CODE: Long
        get() {
            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                getPackageInfo()?.longVersionCode!!
            } else {
                getPackageInfo()?.versionCode!!.toLong()
            }
        }

    /**
     * 获取手机IMEI(需要“android.permission.READ_PHONE_STATE”权限)
     *
     * @return 手机IMEI
     */
    @SuppressLint("HardwareIds")
    fun getDeviceId(): String {
        var deviceId: String? = SPUtils.getString("deviceImei")
        if (isUseDeviceId(deviceId)) {
            deviceId = getIMEI()
        }
        if (isUseDeviceId(deviceId)) {
            deviceId = getAndroidId()
        }
        if (isUseDeviceId(deviceId)) {
            deviceId = getMacAddress()
        }
        if (isUseDeviceId(deviceId)) {
            deviceId = Build.SERIAL
        }
        if (isUseDeviceId(deviceId)) {
            deviceId = getMacAddress()
        }
        if (isUseDeviceId(deviceId)) {
            deviceId = getDeviceUUID()
        }
        if (!isUseDeviceId(deviceId)) {
            SPUtils.put("deviceImei", deviceId!!)
        }
        return deviceId!!
    }

    private fun isUseDeviceId(deviceId: String?): Boolean {
        return StringUtils.isEmpty(deviceId) || deviceId.equals("unknown", true) || deviceId == "000000000000000"
    }

    @SuppressLint("HardwareIds")
    fun getSerial(): String? {
        try {
            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                Build.getSerial()
            } else {
                Build.SERIAL
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    @SuppressLint("HardwareIds")
    fun getIMEI(): String? {
        val context = Utils.instance.context.applicationContext
        val mManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager? ?: return null
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            try {
                if (!StringUtils.isEmpty(mManager.imei)) {
                    return mManager.imei
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
        try {
            if (!StringUtils.isEmpty(mManager.deviceId)) {
                return mManager.deviceId
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        try {
            if (!StringUtils.isEmpty(mManager.subscriberId)) {
                return mManager.subscriberId
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    /**
     * 获取MAC地址
     */
    @SuppressLint("HardwareIds")
    fun getMacAddress(): String? {
        try {
            val context = Utils.instance.context.applicationContext
            val mManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
            return mManager.connectionInfo.macAddress
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    /**
     * 获取AndroidId
     */
    @SuppressLint("HardwareIds")
    fun getAndroidId(): String? {
        try {
            val context = Utils.instance.context.applicationContext
            return Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    /**
     * 通过UUID生成设备唯一标识
     */
    @SuppressLint("HardwareIds")
    fun getDeviceUUID(): String {
        val devIDShort = "35" +
                Build.BOARD.length % 10 +
                Build.BRAND.length % 10 +
                Build.DEVICE.length % 10 +
                Build.DISPLAY.length % 10 +
                Build.HOST.length % 10 +
                Build.ID.length % 10 +
                Build.MANUFACTURER.length % 10 +
                Build.MODEL.length % 10 +
                Build.PRODUCT.length % 10

        return UUID(devIDShort.hashCode().toLong(), Build.SERIAL.hashCode().toLong()).toString()
    }

    /**
     * 获取包名信息
     */
    fun getPackageInfo(): PackageInfo? {
        var pi: PackageInfo? = null
        try {
            val pm = Utils.instance.context.packageManager
            pi = pm.getPackageInfo(Utils.instance.context.packageName, PackageManager.GET_CONFIGURATIONS)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return pi
    }

    /**
     * 重启系统
     * */
    fun reBootDevice() {
        createSuProcess("reboot")!!.waitFor()
    }

    /**
     * 重启设备只需要 createSuProcess("reboot").waitFor();
     */
    @Throws(IOException::class)
    fun createSuProcess(cmd: String): Process? {
        var os: DataOutputStream? = null
        val process: Process? = createSuProcess()
        try {
            os = DataOutputStream(process!!.outputStream)
            os.writeBytes(cmd + "\n")
            os.writeBytes("exit $?\n")
        } finally {
            if (os != null) {
                try {
                    os.close()
                } catch (_: IOException) {
                }
            }
        }
        return process
    }

    @Throws(IOException::class)
    fun createSuProcess(): Process? {
        val rootUser = File("/system/xbin/ru")
        return if (rootUser.exists()) {
            Runtime.getRuntime().exec(rootUser.absolutePath)
        } else {
            Runtime.getRuntime().exec("su")
        }
    }

    fun resetAPP(context: Context) {
        val intent =
            context.packageManager.getLaunchIntentForPackage(context.packageName)
        intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        context.startActivity(intent)
    }

    /**
     * 设备休眠
     */
    fun sleepDevice() {
        val powerManager = Utils.instance.context.getSystemService(Context.POWER_SERVICE) as PowerManager
        val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::SleepDevice")
        wakeLock.acquire(10 * 60 * 1000L)
        wakeLock.release()
    }

    /**
     * 关机
     */
    fun shutdownDevice() {
        try {
            // 使用 'reboot -p' 来关机
            val process = Runtime.getRuntime().exec("reboot -p")
            process.waitFor()
        } catch (e: IOException) {
            e.printStackTrace()
        } catch (e: InterruptedException) {
            e.printStackTrace()
        }
    }

    /**
     * 获取屏幕亮度
     */
    fun getSystemScreenBrightness(activity: Activity): Int {
        val resolver = Utils.instance.context.contentResolver
        return Settings.System.getInt(resolver, Settings.System.SCREEN_BRIGHTNESS)
    }

    /**
     * 修改系统屏幕亮度
     */
    fun setSystemScreenBrightness(activity: Activity, brightness: Int) {
        val resolver = Utils.instance.context.contentResolver
        Settings.System.putInt(resolver, Settings.System.SCREEN_BRIGHTNESS, brightness)
    }

    /**
     * 修改系统时区
     */
    fun setTimeZone(timeZoneId: String) {
        try {
            val process = Runtime.getRuntime().exec("su")
            val os = process.outputStream
            os.write("echo \"$timeZoneId\" > /etc/timezone\n".toByteArray())
            os.write("setprop persist.sys.timezone $timeZoneId\n".toByteArray())
            os.write("exit\n".toByteArray())
            os.flush()
            os.close()
            process.waitFor()
            L.d("Time zone changed to: $timeZoneId")
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 修改系统日期与时间
     */
    fun setDateTime(dateTime: String) {
        try {
            val process = Runtime.getRuntime().exec("su")
            val os = process.outputStream
            os.write("data -s \"$dateTime\"".toByteArray())
            os.write("exit\n".toByteArray())
            os.flush()
            os.close()
            process.waitFor()
            L.d("DateTime changed to: $dateTime")
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 通过ADB命令永久授权
     */
    fun grantWriteSecureSettings(vararg permissions: String) {
        try {
            val packageName = getPackageInfo()?.packageName
            L.i("设置权限的包名：$packageName")
            val process = Runtime.getRuntime().exec("su")
            val os = process.outputStream
            for (e in permissions) {
                try {
                    os.write("pm grant $packageName $e\n".toByteArray())
                    os.flush()
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
            os.write("exit\n".toByteArray())
            os.flush()
            process.waitFor()
            L.i("ADB权限申请完成")
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 检测设备是否root
     */
    fun isDeviceRooted(): Boolean {
        val paths = arrayOf(
            "/system/bin/su",
            "/system/xbin/su",
            "/system/app/Superuser.apk",
            "/data/local/xbin/su",
            "/data/local/bin/su",
            "/system/sd/xbin/su",
            "/system/bin/failsafe/su",
            "/data/local/su"
        )

        for (path in paths) {
            if (File(path).exists()) {
                return true
            }
        }
        return false
    }

    /**
     * 请求root权限
     */
    fun requestRootAccess(): Boolean {
        return try {
            val process = Runtime.getRuntime().exec("su")
            process.outputStream.write("exit\n".toByteArray())
            process.outputStream.flush()
            process.waitFor() == 0
        } catch (e: Exception) {
            false
        }
    }

    /**
     * 跳转权限设置页面
     */
    fun goToAppSettings(activity: Activity) {
        val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
        val uri = Uri.fromParts("package", activity.packageName, null)
        intent.data = uri
        activity.startActivity(intent)
    }
}